/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { Dimensions, PixelRatio } from 'react-native';
import { Avoid } from '@hadss/react_native_avoid_area';
import { AvoidArea, AvoidAreaType } from '@hadss/react_native_avoid_area/src/turbo/NativeAvoidModule';

interface AvoidAreaContextType {
    topRectHeight: number;
    bottomRectHeight: number;
    orientation: string;
    cutoutMargin: number;
    isWideDevice: boolean;
    isHighDevice: boolean;
    isStoreNeedAvoid: boolean;
    isWideCutout: boolean;
}

const AvoidAreaContext = createContext<AvoidAreaContextType | undefined>(undefined);

interface AvoidAreaProviderProps {
    children: ReactNode;
}

export const AvoidAreaProvider: React.FC<AvoidAreaProviderProps> = ({ children }) => {
    const [topRectHeight, setTopRectHeight] = useState(0);
    const [bottomRectHeight, setBottomRectHeight] = useState(0);
    const [orientation, setOrientation] = useState<string>('');
    const [cutoutMargin, setCutoutMargin] = useState(0);
    const [isWideDevice, setIsWideDevice] = useState(false);
    const [isHighDevice, setIsHighDevice] = useState(false);
    const [isStoreNeedAvoid, setIsStoreNeedAvoid] = useState(false);
    const [isWideCutout, setIsWideCutout] = useState(false);

    const pixelRatio = PixelRatio.get() ? PixelRatio.get() : 1;

    const calcCutoutAvoidArea = (avoidArea: AvoidArea) => {
        const windowWidth = Dimensions.get('window').width;
        const windowHeight = Dimensions.get('window').height;
        const wideScreen = 600
        setIsStoreNeedAvoid(false);
        setIsWideDevice(windowWidth > wideScreen);
        setIsHighDevice(windowHeight > wideScreen);
        setCutoutMargin(0);
        setIsWideCutout(false);
        if (avoidArea.topRect.height) {
            let cutoutAtMiddle = ((avoidArea.topRect.left) / pixelRatio) < (windowWidth / 2);
            if (cutoutAtMiddle || !avoidArea.topRect.left) {
                setIsWideCutout(avoidArea.topRect.width > 100);
                setOrientation('topRectMiddle');
                setCutoutMargin(0);
            } else {
                setOrientation('topRect');
                let margin = windowWidth - avoidArea.topRect.left / pixelRatio;
                setCutoutMargin(margin);
            }
        } else if (avoidArea.leftRect.height) {
            let cutoutAtMiddle = ((avoidArea.leftRect.top) / pixelRatio) < (windowHeight / 2) && ((avoidArea.leftRect.top) / pixelRatio) > (windowHeight / 4);
            if (cutoutAtMiddle || !avoidArea.leftRect.top) {
                setOrientation('leftRectMiddle');
            } else {
                setOrientation('leftRect');
            }
            let margin = (avoidArea.leftRect.width + avoidArea.leftRect.left) / pixelRatio;
            setCutoutMargin(margin);

        } else if (avoidArea.bottomRect.height) {
            let cutoutAtMiddle = ((avoidArea.bottomRect.left) / pixelRatio) > (windowWidth / 4);
            if (cutoutAtMiddle || !avoidArea.bottomRect.left) {
                setIsStoreNeedAvoid(true);
                setOrientation('bottomRectMiddle');
                let margin = windowHeight - avoidArea.bottomRect.top / pixelRatio;
                let height = avoidArea.bottomRect.height / pixelRatio;
                setCutoutMargin(margin + height);
            } else {
                setOrientation('bottomRect');
                let margin = (avoidArea.bottomRect.width + avoidArea.bottomRect.left) / pixelRatio;
                setCutoutMargin(margin);
            }
        } else if (avoidArea.rightRect.height) {
            let cutoutAtMiddle = avoidArea.rightRect.top / pixelRatio < (windowHeight / 2);
            if (cutoutAtMiddle || !avoidArea.rightRect.top) {
                setOrientation('rightRectMiddle');
            } else {
                setOrientation('rightRect');
            }
            let margin = windowWidth - (avoidArea.rightRect.left / pixelRatio);
            setCutoutMargin(margin);
        } else {
            setOrientation('');
            setCutoutMargin(0);
        }
    };

    const initAvoidArea = () => {
        // 状态栏
        let type = AvoidAreaType.TYPE_SYSTEM;
        let avoidArea = Avoid.getWindowAvoidArea(type);
        let topHeight = avoidArea.topRect.height / pixelRatio;
        setTopRectHeight(topHeight);

        // 导航条
        type = AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
        avoidArea = Avoid.getWindowAvoidArea(type);
        let bottomHeight = avoidArea.bottomRect.height / pixelRatio;
        setBottomRectHeight(bottomHeight);

        // 刘海屏
        type = AvoidAreaType.TYPE_CUTOUT;
        avoidArea = Avoid.getWindowAvoidArea(type);
        calcCutoutAvoidArea(avoidArea);
    };

    useEffect(() => {
        //初始化时获取区域避让数据
        initAvoidArea();
        //监听区域避让数据变化S
        Avoid.addAvoidAreaListener((data) => {

            if (data.type === AvoidAreaType.TYPE_SYSTEM) {
                // 状态栏
                let type = AvoidAreaType.TYPE_SYSTEM;
                let avoidArea = Avoid.getWindowAvoidArea(type);
                let topHeight = avoidArea.topRect.height / pixelRatio;
                setTopRectHeight(topHeight);
            } else if (data.type === AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
                // 导航条
                let type = AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
                let avoidArea = Avoid.getWindowAvoidArea(type);
                let bottomHeight = avoidArea.bottomRect.height / pixelRatio;
                setBottomRectHeight(bottomHeight);
            } else if (data.type === AvoidAreaType.TYPE_CUTOUT) {

                calcCutoutAvoidArea(data.area);
            }
        });

        return () => {
            Avoid.removeAvoidAreaListener();
        };
    }, []);

    const contextValue: AvoidAreaContextType = {
        topRectHeight,
        bottomRectHeight,
        orientation,
        cutoutMargin,
        isWideDevice,
        isHighDevice,
        isStoreNeedAvoid,
        isWideCutout
    };

    return (
        <AvoidAreaContext.Provider value={contextValue}>
            {children}
        </AvoidAreaContext.Provider>
    );
};

export const useAvoidArea = (): AvoidAreaContextType => {
    const context = useContext(AvoidAreaContext);
    if (context === undefined) {
        throw new Error('useAvoidArea must be used within an AvoidAreaProvider');
    }
    return context;
};